//
//  keychain.m
//  iCodeMacRun
//
//  Created by Andrew Barry on 22/04/09.
//  Copyright 2009 Barry Computer Services. All rights reserved.
//

#import "keychain.h"

static JSBool keychainAddInternetPassword(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
	if (argc < 3)
		return JS_TRUE;
	
	NSString *server = valToString(cx, argv[0]);
	NSString *accountName = valToString(cx, argv[1]);
	NSString *password = valToString(cx, argv[2]);
	NSString *protocol = @"http";
	
	if (argc >= 4)
		protocol = valToString(cx, argv[3]);

	const char *strServer = [server UTF8String];
	const char *strAccount = [accountName UTF8String];
	const char *strPassword = [password UTF8String];

	SecKeychainAddInternetPassword(nil,
		 strlen(strServer),
		 strServer,
		 0,
		 nil,
		 strlen(strAccount),
		 strAccount,
		 0,
		 "",
		 0,
		 kSecProtocolTypeHTTP,
		 kSecAuthenticationTypeDefault,
		 strlen(strPassword),
		 strPassword,
		 nil);
	return JS_TRUE;
}

static JSBool keychainGetInternetPassword(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
	if (argc < 2)
		return JS_TRUE;
	
	NSString *server = valToString(cx, argv[0]);
	NSString *accountName = valToString(cx, argv[1]);
	NSString *protocol = @"http";
	
	if (argc >= 3)
		protocol = valToString(cx, argv[2]);
	
	const char *strServer = [server UTF8String];
	const char *strAccount = [accountName UTF8String];
	
	UInt32 passwordLength = 0;
	void *passwordData = nil;
	
	OSStatus err = SecKeychainFindInternetPassword (nil,
											  strlen(strServer),
											  strServer,
											  0,
											  nil,
											  strlen(strAccount),
											  strAccount,
											  0,
											  "",
											  0,
											  kSecProtocolTypeHTTP,
											  kSecAuthenticationTypeDefault,
											  &passwordLength,
											  &passwordData,
											  nil);

	if (err == noErr) {
		NSString *password = [NSString stringWithCString:passwordData length:passwordLength];
		*rval = stringToVal(cx, password);
		SecKeychainItemFreeContent(nil, passwordData);
	} else {
		*rval = JSVAL_NULL;
	}
	
	return JS_TRUE;
}

JSObject *keychainObject;

void registerKeychain(JSContext *cx, JSObject *global) {
	JS_AddRoot(cx, &keychainObject);
	
	keychainObject = JS_NewObject(cx, nil, nil, nil);
	JS_DefineProperty(cx, global, "Keychain", OBJECT_TO_JSVAL(keychainObject), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT);
	
	JS_DefineFunction(cx, keychainObject, "storeInternetPassword", keychainAddInternetPassword, 3, 0);
	JS_DefineFunction(cx, keychainObject, "loadInternetPassword", keychainGetInternetPassword, 2, 0);
}
